<template>
  <div class="code-inputs">
    <input
      v-for="(c, index) in code"
      :key="index"
      :ref="'code' + index"
      :value="code[index]"
      class="code-box"
      :class="{ wave: isWaving }"
      :style="{ animationDelay: (index * 0.1) + 's' }"
      maxlength="2"
      @input="onInput(index, $event)"
      @paste="onPaste($event)"
      @keydown.backspace="onBackspace(index, $event)"
      @keydown="onKeydown(index, $event)"
    >
  </div>
</template>

<script>
export default {
  name: 'CodeInput',
  props: {
    length: {
      type: Number,
      default: 6
    }
  },
  data() {
    return {
      code: Array(this.length).fill(''),
      isWaving: false
    }
  },
  mounted() {
    this.playWave() // 加载时播放一次
  },
  methods: {
    playWave() {
      this.isWaving = false
      this.$nextTick(() => {
        this.isWaving = true
        setTimeout(() => {
          this.isWaving = false
        }, this.length * 100 + 600) // 动画总时长后清理
      })
    },
    onInput(index, e) {
      let value = e.target.value.replace(/[^0-9a-zA-Z]/g, '')
      if (value.length > 1) {
        value = value.replace(this.code[index], '')
      }

      this.$set(this.code, index, value)

      if (value) {
        const nextIndex = index + 1
        if (nextIndex < this.code.length) {
          this.$refs['code' + nextIndex][0].focus()
        } else {
          // 播放验证动画
          this.playWave()
          this.$emit('complete', this.code.join(''))
        }
      }
    },
    onPaste(e) {
      e.preventDefault()
      const pasteData = e.clipboardData.getData('text').replace(/[^0-9a-zA-Z]/g, '')

      for (let i = 0; i < this.length; i++) {
        this.$set(this.code, i, pasteData[i] || '')
      }

      const lastIndex = Math.min(pasteData.length, this.length) - 1
      if (lastIndex >= 0) this.$refs['code' + lastIndex][0].focus()

      if (pasteData.length === this.length) {
        this.playWave()
        this.$emit('complete', this.code.join(''))
      }
    },
    clear() {
      this.code = Array(this.length).fill('')
    },
    focusFirst() {
      this.$nextTick(() => {
        if (this.$refs.code0) {
          this.$refs.code0[0].focus()
        }
      })
    },
    onBackspace(index, e) {
      if (!this.code[index]) {
        const prevIndex = index - 1
        if (prevIndex >= 0) {
          this.$set(this.code, prevIndex, '')
          this.$refs['code' + prevIndex][0].focus()
        }
      } else {
        this.$set(this.code, index, '')
      }
    },
    onKeydown(index, e) {
      if (['ArrowLeft', 'ArrowUp'].includes(e.key)) {
        const prevIndex = index - 1
        if (prevIndex >= 0) {
          this.$refs['code' + prevIndex][0].focus()
        }
      } else if (['ArrowRight', 'ArrowDown'].includes(e.key)) {
        const nextIndex = index + 1
        if (nextIndex < this.code.length) {
          this.$refs['code' + nextIndex][0].focus()
        }
      }
    }
  }
}
</script>

<style scoped>
.code-inputs {
  display: flex;
  justify-content: space-between;
  max-width: 300px;
  margin: 16px auto;
  gap: 8px;
}

.code-box {
  width: 40px;
  height: 50px;
  text-align: center;
  font-size: 20px;
  border: 1px solid #ccc;
  border-radius: 6px;
}

.code-box:focus {
  border-color: #0084ff;
  outline: none;
  box-shadow: 0 0 2px #0084ff;
}

/* 波浪动画 */
@keyframes waveAnim {
  0% { transform: translateY(0); }
  30% { transform: translateY(-10px); }
  60% { transform: translateY(5px); }
  100% { transform: translateY(0); }
}

.wave {
  animation: waveAnim 0.6s ease;
}
</style>
